{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "f04dd603-a2d1-48ce-8c17-9f1dba8de1ee",
   "metadata": {},
   "source": [
    "Chapter 10\n",
    "\n",
    "# 截距为0的一元线性回归模型\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccafb456-2453-4c82-8a65-b1963a370cb2",
   "metadata": {},
   "source": [
    "这段代码完整地实现了**通过原点的一元线性回归模型**的建立、参数估计、误差分析与可视化。不同于带截距的线性模型，这里我们**显式地假设回归直线通过原点**，即没有常数项 $b_0$，模型形式是：\n",
    "\n",
    "$$\n",
    "\\hat{y} = b_1 x\n",
    "$$\n",
    "\n",
    "从数学角度来看，我们的目标是：给定样本数据点 $(x_1, y_1), \\dots, (x_n, y_n)$，在假设 $b_0 = 0$ 的前提下，找到一个斜率参数 $b_1$，使得预测值 $\\hat{y}_i = b_1 x_i$ 尽可能接近实际观测值 $y_i$，即使得残差平方和最小。\n",
    "\n",
    "---\n",
    "\n",
    "设向量形式的自变量为 $X \\in \\mathbb{R}^{n \\times 1}$，因变量为 $\\boldsymbol{y} \\in \\mathbb{R}^{n \\times 1}$，我们拟合的模型为：\n",
    "\n",
    "$$\n",
    "\\hat{\\boldsymbol{y}} = X b\n",
    "$$\n",
    "\n",
    "其中 $b \\in \\mathbb{R}^{1 \\times 1}$ 是我们要求的斜率参数。最小二乘法的目标是最小化预测值与真实值之间的 $L^2$ 距离，即最小化下式：\n",
    "\n",
    "$$\n",
    "J(b) = \\| \\boldsymbol{y} - X b \\|_2^2\n",
    "$$\n",
    "\n",
    "对 $b$ 求导并令导数为零，可得到最优解满足正规方程：\n",
    "\n",
    "$$\n",
    "X^\\top X b = X^\\top \\boldsymbol{y}\n",
    "$$\n",
    "\n",
    "从而斜率 $b$ 的显式表达为：\n",
    "\n",
    "$$\n",
    "b = (X^\\top X)^{-1} X^\\top \\boldsymbol{y}\n",
    "$$\n",
    "\n",
    "这是代码中使用 `np.linalg.inv(X.T @ X) @ X.T @ y` 这一行所求出的参数。\n",
    "\n",
    "---\n",
    "\n",
    "为了进一步理解这个过程，代码还分别打印或计算了：\n",
    "\n",
    "- $X^\\top X$：这个是**格拉姆矩阵（Gram matrix）**，本质上是 $x_i$ 自身的平方和；\n",
    "- $X^\\top \\boldsymbol{y}$：输入与输出的“协变量积”，即 $\\sum x_i y_i$；\n",
    "- $(X^\\top X)^{-1}$：格拉姆矩阵的逆，是参数计算中不可或缺的部分；\n",
    "- 最终参数 $b$，表示最佳拟合斜率。\n",
    "\n",
    "---\n",
    "\n",
    "接着，代码构造了一个新的 $x$ 数值范围（从 0 到 10 的等距点），用于在该区间内生成预测值 $\\hat{y}_{\\text{new}} = b x_{\\text{new}}$，从而可以绘制一条完整的回归直线。\n",
    "\n",
    "训练集上的预测值则为：\n",
    "\n",
    "$$\n",
    "\\hat{\\boldsymbol{y}} = X b\n",
    "$$\n",
    "\n",
    "预测误差向量为：\n",
    "\n",
    "$$\n",
    "\\boldsymbol{e} = \\boldsymbol{y} - \\hat{\\boldsymbol{y}}\n",
    "$$\n",
    "\n",
    "并进一步计算其 $L^2$ 范数的平方：\n",
    "\n",
    "$$\n",
    "\\|\\boldsymbol{e}\\|_2^2 = \\boldsymbol{e}^\\top \\boldsymbol{e}\n",
    "$$\n",
    "\n",
    "这个值即为残差平方和（Residual Sum of Squares, RSS），用于衡量拟合效果的好坏，越小代表模型预测越精确。\n",
    "\n",
    "---\n",
    "\n",
    "在可视化部分，代码通过以下方式直观展现了模型：\n",
    "\n",
    "- 蓝色叉点 (`x`) 表示原始观测数据 $(x_i, y_i)$；\n",
    "- 红色直线是预测函数 $\\hat{y} = b x$ 在 $[0, 10]$ 区间上的图像；\n",
    "- 红色叉点是训练集上预测值 $(x_i, \\hat{y}_i)$；\n",
    "- 每个样本的预测值与真实值之间的橙色线段表示误差（残差）；\n",
    "- 图像添加了坐标轴标签、网格与等比例比例尺，美观且清晰。\n",
    "\n",
    "---\n",
    "\n",
    "总之，这段代码展示的是**不含截距项的最小二乘回归**，数学上简洁，直观上表现为一条穿过原点的最佳拟合直线，通过矩阵计算与可视化清楚地揭示了误差最小化的几何含义。如果需要，我还可以对比它与带截距模型的差异。是否继续？"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7dc709a-16b7-4294-ac0f-edc88b17b5a6",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "cc1230b5-4697-4042-b4d3-4ef837b679de",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e959af90-722c-4b04-be3d-f86a1cdcc27b",
   "metadata": {},
   "source": [
    "## 数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0106797b-43ea-4c1a-a174-417e09856a47",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = np.array([1,2,3,5,6,7,8,9]).reshape(-1,1)   # 自变量 x\n",
    "y = np.array([3,1,4,6,5,8,7,8]).reshape(-1,1)   # 因变量 y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "4c07bcd3-b009-42a9-b4c0-e4a942d48b93",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造设计矩阵，截距项为0，不需要全1列向量\n",
    "X = x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb519405-48f5-446a-b71e-886588de4fd0",
   "metadata": {},
   "source": [
    "## 计算参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d4118313-b594-42a0-981e-ce880345ed5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.97026022]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = np.linalg.inv(X.T @ X) @ X.T @ y\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "3679ea5c-c5c0-4bd8-ae2c-46a20c61f045",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[269]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 格拉姆矩阵\n",
    "X.T @ X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "8d0bb717-7a80-48a3-9db1-fca2cdf2daa0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.00371747]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 格拉姆矩阵的逆\n",
    "np.linalg.inv(X.T @ X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9716b5bb-687a-4010-9f48-347ddc1ff21c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[261]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.T @ y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c92b1065-2395-43c1-8229-ac0a9a00af93",
   "metadata": {},
   "source": [
    "## 计算预测值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "28434844-10a5-4cfa-82c0-2436f99ae0cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_array = np.linspace(0,10).reshape(-1,1)\n",
    "X_array = x_array\n",
    "\n",
    "y_array_pred = X_array @ b\n",
    "y_pred = X @ b"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2176d694-2190-4234-a5e1-53184597bf3b",
   "metadata": {},
   "source": [
    "## 误差向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "c16f7f1c-a5e4-4816-958b-c17b06c3ca9d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2.02973978],\n",
       "       [-0.94052045],\n",
       "       [ 1.08921933],\n",
       "       [ 1.14869888],\n",
       "       [-0.82156134],\n",
       "       [ 1.20817844],\n",
       "       [-0.76208178],\n",
       "       [-0.73234201]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "error = y - y_pred\n",
    "error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "8ca079a2-d19e-449c-ad0f-87e6a2387005",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[10.76208178]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 误差向量的L2范数的平方\n",
    "error.T @ error"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "611ac6d0-58db-4c31-b958-2445ab46d620",
   "metadata": {},
   "source": [
    "## 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "0527f39f-5eb9-41b0-9b83-8f6a7172bcef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 500x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(5,5))\n",
    "\n",
    "# 绘制样本数据\n",
    "ax.scatter(x, y, marker = 'x', color = 'b')\n",
    "\n",
    "# 绘制回归直线\n",
    "ax.plot(x_array, y_array_pred, color='r')\n",
    "\n",
    "# 绘制预测值\n",
    "ax.scatter(x, y_pred, marker = 'x', color='r')\n",
    "\n",
    "# 绘制误差\n",
    "ax.plot(([i for i in x.squeeze()], [i for i in x.squeeze()]),\n",
    "        ([j for j in y_pred.squeeze()], [j for j in y.squeeze()]),\n",
    "         c='#FFC000', alpha = 0.5)\n",
    "\n",
    "# 装饰\n",
    "ax.set_xlabel('x')\n",
    "ax.set_ylabel('y')\n",
    "ax.set_xlim(0,10)\n",
    "ax.set_ylim(0,10)\n",
    "ax.set_xticks(np.arange(11))\n",
    "ax.set_yticks(np.arange(11))\n",
    "ax.grid(True, c = '0.8')\n",
    "ax.set_aspect('equal', 'box')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "954b7525-dcef-47cb-af13-40c741ca3891",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "070c3389-8048-43a3-baa7-6666009bce96",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
